package org.puremvc.as3.multicore.patterns.mediator
{
	import com.adobe.Reflection;
	
	import flash.utils.Dictionary;
	
	import org.puremvc.as3.multicore.interfaces.IMediator;
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.interfaces.IProxy;

	/**
	 * Advanced PureMVC Mediator. Could be used as a so called generic mediator. A generic mediator
	 * is a view with build in mediator functionality. For views with very special functionality that 
	 * doesn't have to be reusable, this reduces programming overhead.
	 * 
	 * Metadata: HandleNotification
	 *  
	 * @author sven
	 * 
	 */
	public class ReMediator extends Mediator implements IMediator
	{
		public static const HANDLEEVENT:String = 'HandleNotification';
		
		private var _handles:Dictionary = new Dictionary();
		
		private var _notificationHandler:Object = this;
		
		public function ReMediator(mediatorName:String=null, viewComponent:Object=null, genericMediator:Boolean = false)
		{
			super(mediatorName, viewComponent);
			if (genericMediator) {
				_notificationHandler = viewComponent;
			}
		}
		
		override public function listNotificationInterests():Array {
			_handles = Reflection.mapFunctionsWithMetadata(_notificationHandler, HANDLEEVENT, 'name');
			var list:Array = new Array();
			
			for (var key:String in _handles) {
				list.push(key);
			}
			
			return list;
		}
		
		override public function handleNotification(notification:INotification):void {
			var name:String = notification.getName();
			if (_handles.hasOwnProperty(name)) {
				_handles[name](notification);
			}
		}
		
		public function get handles():Dictionary {
			return _handles;
		}
		
		
		/**
		 * Access a proxy by its name.
		 * 
		 * For generic mediator functionality, this has to be public, to 
		 * be able to access proxies from views.
		 *   
		 * @param name of the proxy
		 * @return the proxy
		 * 
		 */
		public function retrieveProxy(name:String):IProxy {
			return facade.retrieveProxy(name);
		}
		
		protected function retrieveMediator(name:String):IMediator {
			return facade.retrieveMediator(name);
		}
		
		protected function registerMediator(mediator:IMediator):void {
			facade.registerMediator(mediator);
		}
	}
}